iT邦幫忙

2023 iThome 鐵人賽

DAY 9
0

今天我們來介紹另一種object type: Join type

Join type
在同一個索引中,爲document彼此之間建立parent/child的關聯性

我們來建立一個示範的索引

PUT /test
{
  "mappings": {
    "properties": {
      "student_id": {
        "type": "keyword"
      },
      "content": {
        "type": "text"
      },
      "join_field": {
        "type": "join",
        "relations": {
          "question": "answer"
        }
      }
    }
  }
}

設置方式為

  • 設置一個你想要join的欄位(範例中命名為join_field)
  • 設置type: join
  • 設置parent名與child名。範例中我想要question當父元素,answer當子元素

接著我們來創建屬於父元素的document:

PUT /test/_doc/1
{
  "student_id": "1",
  "content": "this is question 1",
  "join_field": {
    "name": "question"
  }
}

子元素

PUT /test/_doc/3?routing=1
{
  "student_id": "3",
  "content": "question 1 answer is A",
  "join_field": {
    "name": "answer",
    "parent": 1
  }
}
  • 首先在創建的時候就必須指定routing,因為必須要在同一個shard上
  • 在子元素的join type field中,必須要指定父元素的id

這時候的情況如下:

  • id = 1之文檔為id = 3之文檔的父元素
  • id = 3之文檔為id = 1之文檔的子元素
    https://ithelp.ithome.com.tw/upload/images/20230911/20161866ja0lGXnFSN.png

實際情境:

假如我想找到id為1的question它底下的答案應該怎麼辦?
(看不懂沒關係,之後在搜尋部分會再提一次,這邊只是簡單讓我們透過實際的code看到真實結果)

GET /test/_search
{
  "query": {
    "parent_id": {
      "type": "answer",
      "id": 1
    }
  }
}

GET /test/_search
{
  "query": {
    "has_parent": {
      "parent_type": "question",
      "query": {
          "match": {
            "content": "question 1"
          }
        }
      }
    }
  }

https://ithelp.ithome.com.tw/upload/images/20230911/20161866bL5npLE2Hg.png
兩種找法都是可以找到答案,上面是如果我們知道父元素id的情形下,下面has parent的則是在不知道父元素的id時可以用的方法。

使用join type的限制:

  • 要建立關連的文檔必須存在同一個索引中
  • 父與子級文檔必須在同一個分片上
  • 一個索引只能有一個欄位是join type
  • 一個文檔只能有一個父元素,但是能有很多個子元素
  • 可以在之後再加入新的relation到已經存在的join欄位
  • 要先有父才能有子,想要指定子元素時,想指定的父元素必須已經配置好了

而這樣的join關係是可以創立多層級的
示意圖如下:
https://ithelp.ithome.com.tw/upload/images/20230911/201618662OKH7ksyuC.png

  • company當作祖父元素
  • company下的子元素有partner跟manager
  • manager作為employee的父元素

設定就會如下

PUT /company
{
  "mappings": {
    "properties": {
      "join_field": {
        "type": "join",
        "relations": {
          "company": ["manager", "partner"],
          "manager": "employee"
        }
      }
    }
  }
}

PUT /company/_doc/1
{
  "name": "my_company",
  "join_field": "company"
}

PUT /company/_doc/2?routing=1
{
  "name": "CEO",
  "join_field": {
    "name": "manager",
    "parent": 1
  }
}
PUT /company/_doc/3?routing=1
{
  "name": "engineer",
  "join_field": {
    "name": "employee",
    "parent": 2
  }
}

注意employee的routing要跟祖父元素的id一樣,但是parent一樣是父元素的id

那我們一起來比較一下這三種類型的object typehttps://ithelp.ithome.com.tw/upload/images/20230911/20161866ITamZIUZh1.png
這邊就把object type都介紹完了~

剩下可能也很常用但是我沒打算特別介紹的就是date類型了吧,但是我覺得要使用時再看官方文檔就可以了~

明天就進入到動態映射(Dynamic mapping)!


上一篇
【Day 8】由淺入深來探討Elasticsearch - Object field type
下一篇
【Day 10】由淺入深來探討Elasticsearch - Dynamic mapping
系列文
由淺入深來探討Elasticsearch,從基礎語法到底層相關原理30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言